﻿--[[
@file   Game list control.
@author jameszhai
@date   2017-04-15
--]]

--[[
// 开始手动添加游戏
MSG_BEGIN(Msg_OnAddGame)
MSG_END

// 取消手动添加游戏
MSG_BEGIN(Msg_OnCancelAddGame)
MSG_END

// 手动添加游戏结果
MSG_BEGIN(Msg_OnAddGameRlt)
    JSONB(int, Result)      // 结果
    JSONB(int, GameID)      // 游戏ID
MSG_END

// 显示启动游戏任务栏
SERVICE_BEGIN(Svr_ShowStartGame)
    JSONB(int, GameID)      // 游戏ID
SERVICE_END
--]]

EListItemIdx = 
{
    liTopList  = 0;     -- 顶部的ITEM列表
    liGameList = 1;     -- 游戏列表
};

ETitleState = 
{
    tsNormal = 0;
    tsHover  = 1;
};

EAddGameRlt = 
{
    arSuccess = 0;      -- Add success
    arExists  = 1;      -- Game already exists
    arInvalid = 2;      -- Not tencent game
    arIllegal = 3;      -- 路径非法
};

EGameListUI = 
{
    sBtnHome = "pnlList\\pnlLeft\\btnHomePage";                 -- 主页
    sBtnGMMgr= "pnlList\\pnlLeft\\pnlTitle\\btnGameMgr";        -- 游戏管理

    sPnlList = "pnlList\\pnlLeft\\pnlGameList";                 -- 游戏列表

    sTitle  = "WondderfulPanelTitle.tpf";
    sPanel  = "WonderfulPanel.tpf";

};


TGMListView = 
{
    ierd_tgp.tpf_ui.Require("TPFLocalization.lua"); 

    InitView = function(dwRoot)
        TGMListView.nBtnHome = ui_utility.get_ctrl_id_by_path(dwRoot, EGameListUI.sBtnHome);

        -- Home按钮
        if not TGMListView.IsValidID(TGMListView.nBtnHome) then
            TGPLog.LogE("GMList", "Home page button is null.");
            return false;
        end;

        ui_utility.setproperty_by_id(TGMListView.nBtnHome, "Caption", LoadStr("BANNER_HOMEPAGE_CHINA"));
        ui_utility.setproperty_by_id(TGMListView.nBtnHome, "OnClick", "TGMListView.OnClkHome");

        -- 初始化列表
        local   dwTempID = ui_utility.get_ctrl_id_by_path(dwRoot, EGameListUI.sPnlList);

        if not TGMListView.IsValidID(dwTempID) then
            TGPLog.LogE("GMList", "Get list panel fail.");
            return false;
        end;

        if TGMListView.InitBanner(dwTempID) then
            local pTPFUI = base_utility.get_component_adapter("ITpf_ui",
                                "ierd_tgp.tpf_ui.GetTPFUI();");
            
            if nil ~= pTPFUI then
                TGMListView.bIsEnVer = pTPFUI:Is_English_ver();
            else
                TGMListView.bIsEnVer = false;
                TGPLog.LogE("GMList", "Init, get TPF UI fail.");
            end;

            comm_center.listen_broadcast("Msg_OnAddGame", "TGMListView.OnAddGame");
            comm_center.listen_broadcast("Msg_OnAddGameRlt", "TGMListView.OnAddGameRlt");
            comm_center.listen_broadcast("Msg_OnCancelAddGame", "TGMListView.OnCelAddGame");

            -- Home按钮选中
            TGMListView.SelectHome(true);

            return true;
        else
            TGPLog.LogE("GMList", "Init panel and banner fail.");
            return false;
        end;
    end;

    UnInitView = function()
    end;

    -- Home Click
    OnClkHome = function(pUILib, nBtnID)
        TGMListView.SelectHome(true);
        TOfflineBtmBar.HideView();

        if TGMListView.IsValidID(TGMListView.dwSelItem) then
            TGMListView.SetSelect(TGMListView.dwSelItem, false);
        end;
    end;

    SelectHome = function(bSelect)
        if bSelect then
            ui_utility.setproperty_by_id(TGMListView.nBtnHome, "Background", 
                "ONEIMAGE:client_mainframe\\mainframe_icon.png?188,15,198,25;Stretch;0;");
--            ui_utility.setproperty_by_id(TGMListView.nBtnHome, "Icon", 
--                "banner_list\\banner_list.png?44,10,68,34;|banner_list\\banner_list.png?44,10,68,34;|banner_list\\banner_list.png?44,10,68,34;");
            local   sColor = "0x00C8FF";
            if base_utility.is_type_of_oversea_ver() then
                sColor = "0xFFC800";
            end
            ui_utility.setproperty_by_id(TGMListView.nBtnHome, "TextColor", sColor);
            ui_utility.setproperty_by_id(TGMListView.nBtnHome, "TextColorHover", sColor);
            ui_utility.setproperty_by_id(TGMListView.nBtnHome, "TextColorPressed", sColor);
        else
            ui_utility.setproperty_by_id(TGMListView.nBtnHome, "Background", "");
--             ui_utility.setproperty_by_id(TGMListView.nBtnHome, "Icon", 
--                "banner_list\\banner_list.png?44,10,68,34;|banner_list\\banner_list.png?44,10,68,34;|banner_list\\banner_list.png?44,10,68,34;");
            ui_utility.setproperty_by_id(TGMListView.nBtnHome, "TextColor",
                "RGB:230,230,230");
            ui_utility.setproperty_by_id(TGMListView.nBtnHome, "TextColorHover",
                "RGB:230,230,230");
            ui_utility.setproperty_by_id(TGMListView.nBtnHome, "TextColorPressed",
                "RGB:230,230,230");
        end
    end;

    -- 更新游戏状态
    UpdateState = function(zState)
        if nil == zState then
            TGPLog.LogE("GMList", "Update state, state is nil.");
            return;
        end;

        for nItem, zItem in pairs(TGMListView.zItemMap) do
            if zItem["GameID"] == zState.iGame_id then
                TGMListView.ChangeState(zItem, zState);
                break;
            end;
        end;
    end;

    -- 设置所有游戏状态
    SetAllState = function(zList)
        for nGameID, zState in pairs(zList) do
            for nItem, zItem in pairs(TGMListView.zItemMap) do
                if zItem["GameID"] == nGameID then
                    TGMListView.ChangeState(zItem, zState);
                    break;
                end;
            end;
        end;
    end;

    -- 修改状态
    ChangeState = function(zItem, zState)
        if nil == zItem or nil == zState then
            TGPLog.LogI("GMList", "Change state, param fail.");
            return;
        end;

        local   dwCtrl = zItem["CtrlID"];
        local   dwRun   = ui_utility.get_ctrl_id_by_path(dwCtrl, "lblRunning");
        local   dwStart = ui_utility.get_ctrl_id_by_path(dwCtrl, "lblStarting");
        local   dwName  = ui_utility.get_ctrl_id_by_path(dwCtrl, "lblNick");

        -- 运行状态
        if (ierd_tgp.game_library.GAME_STATE_RUNNING   == zState.iState) or
           (ierd_tgp.game_library.GAME_STATE_LAUNCHING == zState.iState) then
            zItem["Running"] = true;
            -- 修改状态
            if (ierd_tgp.game_library.GAME_STATE_LAUNCHING == zState.iState) then
                ui_utility.show_ctrl(dwRun  , false);
                ui_utility.show_ctrl(dwStart, true);
            else
                ui_utility.show_ctrl(dwRun  , true);
                ui_utility.show_ctrl(dwStart, false);
            end;

            ui_utility.show_ctrl(dwName, false);
        else
            zItem["Running"] = false;

            -- 修改状态
            ui_utility.show_ctrl(dwName , true);
            ui_utility.show_ctrl(dwRun  , false);
            ui_utility.show_ctrl(dwStart, false);
        end;

        local nGameId = zItem["GameID"];
        TGMListView.UpdateGameTxtColor(dwCtrl, nGameId);
    end;

    -- 设置游戏列表
    SetMyGameList = function(refresh_all_nodes)
        local zList = TOfflineModule.GetMyGameList();
        local zInfo = TOfflineModule.GetGameInfoList();
        if (nil ~= zList) and (nil ~= zInfo) then
            TGMListView.ShowLoading(false);
            TGMListView.UpdateGameList(refresh_all_nodes);
        else
            TGMListView.ShowLoading(false);

            -- 显示没有游戏的提示界面
            if (nil ~= TGMListView.pLvGames) then
                TGMListView.pLvGames:Show(FALSE);
            end;

            if (nil ~= TGMListView.pLoading) then
                TGMListView.pLoading:Show(FALSE);
            end;

            if TGMListView.pNoGameUI then
                TGMListView.pNoGameUI:Show(TRUE);
            end;
        end;
    end;

    -- 更新游戏列表
    UpdateGameList = function(refresh_all_nodes)
        base_utility.remove_interval("TGMListView.OnTickRefreshGameList");
        if (nil == TGMListView.pLvGames) then
            TGPLog.LogE("GMList", "Game list is not created.");
            return;
        end;

        local   dwTemp = TGMListView.pLvGames:GetControlID();

        if refresh_all_nodes then
            ui_utility.setproperty_by_id(dwTemp, "ItemLayoutPath", 
                "offline\\GameItem.tpf/TenioUILayout/UIObject");
        end
        -- 分批加载游戏列表
        local zList = TOfflineModule.GetMyGameList();
        local zInfo = TOfflineModule.GetGameInfoList();
        local zState = TOfflineModule.GetAllState()

        if (nil == zList) or (nil == zInfo) and (zInfo.count == 0) then
            TGPLog.LogI("GMList", "Game information is not ready.");
            return
        end
        -- 开始更新
        TGMListView.pLvGames:BeginUpdate();
        local total_count = table.getn(zList);
        local cur_count = TGMListView.pLvGames:GetItemCount();
        if TGMListView.IsValidID(TGMListView.dwAddGame) then
            if cur_count > 0 then
                TGMListView.pLvGames:RemoveItem(0);
            end
            TGMListView.dwAddGame = 0;
            cur_count = TGMListView.pLvGames:GetItemCount();
        end;

        local refresh_all_games = false; 
        if cur_count < total_count then
            local insert_count = 0;
            if cur_count + TGMListView.ITEM_COUNT_PER_REFRESH < total_count then
                insert_count = TGMListView.ITEM_COUNT_PER_REFRESH;
            else 
                insert_count = total_count - cur_count;
            end
            -- 增加节点数量
            local last_index = cur_count + insert_count - 1;
            if insert_count > 0 then
                for index = cur_count, last_index do
                    TGMListView.pLvGames:InsertItem(index);
                end
            end
        else 
            -- 删除多余的节点
            if cur_count - total_count > 0 then
                for index = cur_count -1, total_count, -1 do
                    TGMListView.pLvGames:RemoveItem(index);
                end
                refresh_all_games = true;
            end
        end

        -- 遍历game_list， 逐一设置数据
        local draggable_list_count = TGMListView.pLvGames:GetItemCount();
        local first_index = cur_count;
        local last_index = draggable_list_count - 1;
        if refresh_all_nodes or refresh_all_games then
            first_index = 0;
        end

        for nIdx = first_index, draggable_list_count - 1 do
            local   nGame  = zList[nIdx + 1];
            local   zData  = zInfo.zInfoMap[nGame];
            local   dwItem = TGMListView.pLvGames:GetItemRootIDByIdx(nIdx);

            -- 更新游戏的基本信息
            if nil ~= zData then
                TGMListView.UpdateBaseInfo(dwItem, zData);
            else
                TGPLog.LogI("GMList", "Game info not find:"..tostring(nGame));
            end;

            -- 消息监听
            local   dwSpyer = ui_utility.get_ctrl_id_by_path(dwItem, "MsgSpy");

            if (TGMListView.IsValidID(dwSpyer)) then
                ui_utility.setproperty_by_id(dwSpyer, "OnMouseHover", 
                                             "TGMListView.OnGameHover");
                ui_utility.setproperty_by_id(dwSpyer, "OnMouseLeave", 
                                             "TGMListView.OnGameLeave");
            end;

            ui_utility.setproperty_by_id(dwItem, "OnClick", "TGMListView.OnGameItemClk");
            ui_utility.setproperty_by_id(dwItem, "OnRButtonDown", "TGMListView.OnShowGMMenu");

            local   zTemp = {};

            zTemp["GameID"] = nGame;
            zTemp["IconID"] = dwItem;
            zTemp["CtrlID"] = dwItem;
            zTemp["Hover" ] = false;
            zTemp["Select"] = false;
            zTemp["IsGame"] = true;

            TGMListView.zItemMap[dwItem] = zTemp;

            -- 状态处理
            if nil ~= zState then
                TGMListView.ChangeState(zTemp, zState[nGame]);
            end;
        end;   -- end of for loop

        -- 结束更新
        TGMListView.pLvGames:EndUpdate();
        -- 判断是否需要继续刷新
        if draggable_list_count < total_count then
             base_utility.add_interval("TGMListView.OnTickRefreshGameList", 400);
        end
        -- 把添加游戏的按钮再添加上
        --if TGMListView.IsValidID(TGMListView.dwAddGame) then
          --  TGMListView.dwAddGame = 0;
            --TGMListView.ShowAddGame();
        --end;
    end;

    UpdateGameTxtColor = function(dwItem, nGame)
        if (nGame == TGMListView.dwSelGame) then
            TGMListView.SetSelect(dwItem, true);
        else
            local   pMask = ui_utility.get_ctrl_ptr_by_path(dwItem, "CntSelectedMask");

            if (nil ~= pMask) then
                pMask:Show(FALSE);
            end;

            local   sColor = "0xFFFFFF";

            if not TGMListView.IsInstalled(nGame) then
                sColor = "0x8C8C8C";
            end;

            local   dwTemp = ui_utility.get_ctrl_id_by_path(dwItem, "lblNick");
            if (TGMListView.IsValidID(dwTemp)) then
                ui_utility.setproperty_by_id(dwTemp, "TextColor", sColor);
            end;

            dwTemp = ui_utility.get_ctrl_id_by_path(dwItem, "lblStarting");
            if (TGMListView.IsValidID(dwTemp)) then
                ui_utility.setproperty_by_id(dwTemp, "TextColor", sColor);
            end;

            dwTemp = ui_utility.get_ctrl_id_by_path(dwItem, "lblRunning");
            if (TGMListView.IsValidID(dwTemp)) then
                ui_utility.setproperty_by_id(dwTemp, "TextColor", sColor);
            end;

            TGMListView.ShowHoverMask(dwItem, false);
        end;
    end;

    -- 更新游戏基本信息
    UpdateBaseInfo = function(dwItemID, zInfo)
        if (nil == zInfo) then
            TGPLog.LogE("GMList", "Update game info, info not find:"..tostring(dwItemID));
            return;
        end;

        -- ICON
        local   dwIcon = ui_utility.get_ctrl_id_by_path(dwItemID, "pnlIcon");
        if (TGMListView.IsValidID(dwIcon)) then
            local   sTemp;

            if zInfo.banner_mini_icon_url ~= nil and zInfo.banner_mini_icon_url ~= "" then
                sTemp = zInfo.banner_mini_icon_url;
            else
                sTemp = zInfo.banner_icon_url;
            end;

            local sIcon = string.format("ONEIMAGE:banner_list\\banner_list.png?78,10,102,34|%s;Stretch;0;", 
                                         sTemp);
            ui_utility.setproperty_by_id(dwIcon, "Background", sIcon);
        end;

        -- Game name
        local   dwNick = ui_utility.get_ctrl_id_by_path(dwItemID, "lblNick");
        if TGMListView.IsValidID(dwNick) then
            if true == TOfflineBtmBar.is_english_ver and zInfo.e_name ~= nil and zInfo.e_name ~= "" then
                ui_utility.setproperty_by_id(dwNick, "Caption", zInfo.e_name);
            else
                ui_utility.setproperty_by_id(dwNick, "Caption", zInfo.name);  -- zInfo.e_name
            end
        end;
    end;

    -- Item点击
    OnNodeClick = function(dwCtrl)
        local   zTemp  = TGMListView.zItemMap[dwCtrl];

        if (nil == zTemp) or (true == zTemp["Select"]) then
            TGPLog.LogI("GMList", "Item already selected.");
            return;
        end;

        if (TGMListView.IsValidID(TGMListView.dwSelItem)) then
            TGMListView.SetSelect(TGMListView.dwSelItem, false);
        else
            TGMListView.SelectHome(false);
        end;

        TGMListView.SetSelect(dwCtrl, true);

        -- 点击了游戏，并且游戏已经安装，才显示低栏
        if (true == zTemp["IsGame"]) and TGMListView.IsInstalled(zTemp["GameID"]) then
            local   zParam = {};
            zParam["GameID"] = zTemp["GameID"];
            comm_center.call_service("Svr_SelectGame", zParam);
        else
            TGPLog.LogI("GMList", "Click item is not game:"..zTemp["GameID"]);
            TOfflineBtmBar.HideView();
        end;
    end;

    -- 点击了游戏项
    OnGameItemClk = function(pUILib, dwCtrl, x, y)
        -- 状态处理
        TGMListView.OnNodeClick(dwCtrl);

        -- 显示游戏
        local   zItem = TGMListView.zItemMap[dwCtrl];

        if nil == zItem then
            TGPLog.LogE("GMList", "Click item, item not find.");
            return;
        end;

        if (TOfflineModule.IsRailGame(zItem["GameID"])) and 
            TGMListView.IsInstalled(zItem["GameID"]) then
            local   zParam = {};

            zParam["GameID"] = zItem["GameID"];
            comm_center.call_service("Svr_ShowStartGame", zParam);

            -- 发送选中游戏通知
            local   zTemp = {};

            zTemp["game_id"] = zItem["GameID"];
            comm_center.send_broadcast("Msg_SelGameNotify", zTemp);
        else
            TGPLog.LogI("GMList", "Not rail game:"..tostring(zItem["GameID"]));
            TOfflineBtmBar.HideView();
        end;
    end;

    -- 显示菜单
    OnShowGMMenu = function(pUILib, dwCtrlID, nXPos, nYPos)
        local   zItem = TGMListView.zItemMap[dwCtrlID];

        if nil == zItem then
            TGPLog.LogE("GMList", "Click item, item not find.");
            return;
        end;

        local   pTemp = ui_utility.get_ctrl_ptr_by_id(dwCtrlID);

        if nil == pTemp then
            TGPLog.LogE("GMList", "Click item, get item fail.");
            return;
        end;

        local   rtTemp = pTemp:GetRectEx(TRUE,TRUE);
        local   zTemp = {};

        zTemp["XOffset"] = rtTemp.left + nXPos;
        zTemp["YOffset"] = rtTemp.top  + nYPos;
        zTemp["GameID" ] = zItem["GameID"];

        comm_center.call_service("Svr_ShowGameMenu", zTemp);
    end;

    -- Hover
    ShowHoverMask = function(dwItemID, bShow)
        local   zTemp = TGMListView.zItemMap[dwItemID];

        if (nil ~= zTemp) then
            local behavior_enter = ui_utility.get_ctrl_ptr_by_path(
                dwItemID, "CntHighlight\\BehaviorEnter");
            local behavior_leave = ui_utility.get_ctrl_ptr_by_path(
                dwItemID, "CntHighlight\\BehaviorLeave");

            if nil == behavior_enter or nil == behavior_leave then
                TGPLog.LogE("GMList", string.format(
                            "behavior_enter or behavior_leave is nil"));
                return;
            end;

            if (true == zTemp["Select"]) and (bShow == zTemp["Hover"]) then
                TGPLog.LogI("GMList", "Item selected, disable show animation.");
                return;
            end;

            if bShow then
                TGPLog.LogI("GMList", string.format("Play enter animation for hove mask"));
                behavior_leave:Stop();
                behavior_enter:Start();
            else
                TGPLog.LogI("GMList", string.format("play leave animation for hove mask"));
                behavior_enter:Stop();
                behavior_leave:Start();
            end;
        end;
    end;

    OnGameHover = function(pUILib, dwItemID, x, y, nFromID)
        TGMListView.OnItemHover(pUILib, dwItemID, x, y, nFromID);
    end;

    OnGameLeave = function(pUILib, dwItemID, x, y, nFromID)
        TGMListView.OnItemLeave(pUILib, dwItemID, x, y, nFromID);
    end;

    OnItemHover = function(pUILib, dwItemID, x, y, nFromID)
        local   dwCtrl = ui_utility.get_ctrl_parent_id(dwItemID);
        local   zTemp  = TGMListView.zItemMap[dwCtrl];

        if (nil ~= zTemp) then
            zTemp["Hover"] = true;
            TGMListView.ShowHoverMask(dwCtrl, true);
        else
            TGPLog.LogE("GMList", "Item hover, information not find.");
        end;
    end;

    OnItemLeave = function(pUILib, dwItemID, x, y, nFromID)
        local   dwCtrl = ui_utility.get_ctrl_parent_id(dwItemID);
        local   zTemp  = TGMListView.zItemMap[dwCtrl];

        if (nil ~= zTemp) and (true == zTemp["Select"]) then
            TGPLog.LogD("GMList", "Leave selected item.");
            return;
        end;

        if (nil ~= zTemp) then
            zTemp["Hover"] = false;
            TGMListView.ShowHoverMask(dwCtrl, false);
        else
            TGPLog.LogE("GMList", "Item hover, information not find.");
        end;
    end;

    -- 选中
    SetSelect = function(dwCtrlID, bSelect)
        local   zTemp = TGMListView.zItemMap[dwCtrlID];

        if (nil == zTemp) then
            TGPLog.LogE("GMList", "Set select fail.");
            return;
        end;

        local   pMask = ui_utility.get_ctrl_ptr_by_path(dwCtrlID, "CntSelectedMask");

        if (nil ~= pMask) then
            ui_utility.setproperty_by_id(pMask:GetControlID(), "Alpha", "255");

            if bSelect then
                pMask:Show(TRUE);
            else
                pMask:Show(FALSE);
            end;
        end;
        
        local   sColor = "0x00C8FF";
        if base_utility.is_type_of_oversea_ver() then
             sColor = "0xFFB219";
        end

        if not bSelect then
            if TGMListView.IsInstalled(zTemp["GameID"]) then
                sColor = "0xFFFFFF";
            else
                sColor = "0x8C8C8C";
            end;
        end;

        local   dwTemp = ui_utility.get_ctrl_id_by_path(dwCtrlID, "lblNick");
        if (TGMListView.IsValidID(dwTemp)) then
            ui_utility.setproperty_by_id(dwTemp, "TextColor", sColor);
        end;

        dwTemp = ui_utility.get_ctrl_id_by_path(dwCtrlID, "lblStarting");
        if (TGMListView.IsValidID(dwTemp)) then
            ui_utility.setproperty_by_id(dwTemp, "TextColor", sColor);
        end;

        dwTemp = ui_utility.get_ctrl_id_by_path(dwCtrlID, "lblRunning");
        if (TGMListView.IsValidID(dwTemp)) then
            ui_utility.setproperty_by_id(dwTemp, "TextColor", sColor);
        end;

        zTemp["Select"] = bSelect;
        zTemp["Hover"]  = bSelect;

        local   zInfo = TGMListView.zItemInfo[zTemp.GameID];

        if nil ~= zInfo then
            if bSelect then
                ui_utility.setproperty_by_id(zTemp["IconID"], 
                    "Background", zInfo.sSelIcon);
            else
                ui_utility.setproperty_by_id(zTemp["IconID"], 
                    "Background", zInfo.sNrlIcon);
                TGMListView.ShowHoverMask(dwCtrlID, bSelect);
            end;
        else
            if not bSelect then
                TGMListView.ShowHoverMask(dwCtrlID, false);
            end;
        end;

        if bSelect then
            TGMListView.dwSelGame = zTemp["GameID"];
            TGMListView.dwSelItem = dwCtrlID;
        else
            TGMListView.dwSelGame = 0;
            TGMListView.dwSelItem = 0;
        end;
    end;

    -- 初始化Banner
    InitBanner = function(dwRoot)
        TGMListView.pLvGames  = ui_utility.get_ctrl_ptr_by_path(dwRoot, "lsGameList");
        TGMListView.pLoading  = ui_utility.get_ctrl_ptr_by_path(dwRoot, "pnlLoading");
        TGMListView.pNoGameUI = ui_utility.get_ctrl_ptr_by_path(dwRoot, "pnlNoGame");

        if (nil == TGMListView.pLvGames) or (nil == TGMListView.pLoading) or
           (nil == TGMListView.pNoGameUI) then
            TGPLog.LogE("GMList", "Get UI control fail.");
            return false;
        end;

        TGMListView.ShowLoading(true);

        local   dwList = TGMListView.pLvGames:GetControlID();

        ui_utility.setproperty_by_id(dwList, "OnMouseWheel", "TGMListView.OnMouseWheel");
        ui_utility.setproperty_by_id(dwList, "OnDLDragEnter", "TGMListView.OnDragEnter");
        ui_utility.setproperty_by_id(dwList, "OnDLDragLeave", "TGMListView.OnDragLeave");
        ui_utility.setproperty_by_id(dwList, "OnDLDragDrop", "TGMListView.OnDragDrop");
        ui_utility.setproperty_by_id(dwList, "OnDLOrderChange", "TGMListView.OnOrderChange");

        return true;
    end;

    OnMouseWheel = function(pUILib, dwCtrlID)
        TGMListView.HideAddGame();
    end;

    OnAddGame = function(zParam)
        TGMListView.ShowAddGame();
    end;

    OnAddGameRlt = function(zParam)
        if nil == zParam then           
            zParam = {};

            zParam["Result"] = EAddGameRlt.arInvalid;

            TGPLog.LogE("GMList", "On add game result, parameter error.");
        end;

        TGMListView.AddGameRlt(zParam);
    end;

    -- 取消添加游戏
    OnCelAddGame = function(zParam)
        TGMListView.HideAddGame();
    end;

    OnDragEnter = function(pUILib, dwCtrlID)
        TGMListView.ShowAddGame();
    end;

    OnDragLeave = function(pUILib, dwCtrlID)
        TGMListView.HideAddGame();
    end;

    -- 拖拽游戏
    OnDragDrop = function(pUILib, dwCtrlID, sFile)
        local pGMLib = base_utility.get_component_adapter("IGame_library",
                        "ierd_tgp.game_library.Get_game_library_adapter();");
        if nil == pGMLib then
            TGPLog.LogE("GMList", "Drag drop, get game lib fail.");
            return;
        end;

        local   zAddRlt = ierd_tgp.game_library.AddGameResultParam:new();
        local   zResult = {};

        pGMLib:add_installed_game(sFile, zAddRlt);

        if (EAddGameRlt.arExists == zAddRlt.result) and 
           (false == pGMLib:IsInMyVisibleGameList(zAddRlt.game_id)) then
            pGMLib:add_or_remove_game(zAddRlt.game_id, true);
        else
            TGPLog.LogI("GMList", "Add game result:"..tostring(zAddRlt.result))
        end;

        zResult["Result"] = zAddRlt.result;
        zResult["GameID"] = zAddRlt.game_id;

        TGMListView.AddGameRlt(zResult);
        
        if zAddRlt.result == ierd_tgp.game_library.MULTI_MATCH then
            event_center.send_event(banner_event.ADD_GAME_CONFLICT, base_utility.table_to_json({path = sFile}));
        end;
        zAddRlt:delete();
    end;

    -- 添加游戏结果
    AddGameRlt = function(zParam)
        if EAddGameRlt.arSuccess == zParam.Result then
            TGMListView.HideAddGame();
        elseif EAddGameRlt.arExists == zParam.Result then
            ui_utility.setproperty_by_path(TGMListView.dwAddGame, "StateIcon", 
                "Background", "ONEIMAGE:bottom_bar\\bottom_bar.png?146,201,166,221;Center;0;"); 
            ui_utility.setproperty_by_path(TGMListView.dwAddGame, "ResultTxt",
                "TextColor", "RGB:246,73,73");
            ui_utility.setproperty_by_path(TGMListView.dwAddGame, "ResultTxt",
                "Caption", LoadStr(ID_ADDING_GAME_GAME_EXIST));
            TGMListView.StartTimer();
        else
            ui_utility.setproperty_by_path(TGMListView.dwAddGame, "StateIcon", 
                "Background", "ONEIMAGE:bottom_bar\\bottom_bar.png?146,201,166,221;Center;0;"); 
            ui_utility.setproperty_by_path(TGMListView.dwAddGame, "ResultTxt",
                "TextColor", "RGB:246,73,73");
            ui_utility.setproperty_by_path(TGMListView.dwAddGame, "ResultTxt",
                "Caption", LoadStr(ID_ADDING_GAME_GAEM_UNKNOW));
            TGMListView.StartTimer();
        end;        
    end;

    StartTimer = function()
        local pTPFUI = base_utility.get_component_adapter("ITpf_ui",
                    "ierd_tgp.tpf_ui.GetTPFUI();");
        if (nil ~= pTPFUI) then
            pTPFUI:AddInterval("TGMListView.OnTimer", 1 * 1000);
        end;
    end;

    StopTimer = function()
        local pTPFUI = base_utility.get_component_adapter("ITpf_ui",
                    "ierd_tgp.tpf_ui.GetTPFUI();");
        if (nil ~= pTPFUI) then
            pTPFUI:RemoveInterval("TGMListView.OnTimer");
        end;
    end;

    -- 添加游戏定时器
    OnTimer = function()
        TGMListView.StopTimer();
        TGMListView.HideAddGame();
    end;

    -- 改变了顺序
    OnOrderChange = function(pUILib, dwCtrlID, bDragMove)
        if not bDragMove then
            TGPLog.LogI("GMList", "Not drag change list order.");
            return;
        end;

        local pGMLib =
                base_utility.get_component_adapter("IGame_library",
                "ierd_tgp.game_library.Get_game_library_adapter();");

        if nil == pGMLib then
            TGPLog.LogE("GMList", "Order, Get game library fail.");
            return;
        end;

        if nil == TGMListView.pLvGames then
            TGPLog.LogE("GMList", "Order change, drag list is nil.");
            return;
        end;

        local   nCount = TGMListView.pLvGames:GetItemCount();

        if (nCount <= 0) then
            TGPLog.LogE("GMList", "Game list is empty.")
            return;
        end;

        if nCount > ierd_tgp.GAME_LIB_MAX_GAME_COUNT then
            TGPLog.LogE("GMList", "Bigger than max game count:"..tostring(nCount));
            nCount = ierd_tgp.GAME_LIB_MAX_GAME_COUNT;
        end;

        local   zList  = ierd_tgp.game_library.Game_list:new();
        local   nGMIdx = 0;
        local   sDebug = "";

        for nIdx = 0, nCount - 1 do
            local   dwItem = TGMListView.pLvGames:GetItemRootIDByIdx(nIdx);
            local   zTemp  = TGMListView.zItemMap[dwItem];

            if (nil ~= zTemp) and (true == zTemp["IsGame"]) then
                zList.game_id_list[nGMIdx] = zTemp["GameID"];
                nGMIdx = nGMIdx + 1;

                if ("" == sDebug) then
                    sDebug = tostring(zTemp["GameID"]);
                else
                    sDebug = sDebug .. "," .. tostring(zTemp["GameID"]);
                end;

                if (true == zTemp["Select"]) then
                    TGMListView.SetSelect(dwItem, false);
                    TGMListView.dwSelGame = zTemp["GameID"];
                end;
            else
                TGPLog.LogE("GMList", "Not a game.");
            end;
        end;

        TGPLog.LogI("GMList", "Game order:"..sDebug);
        zList.count = nGMIdx;
        pGMLib:change_game_order(zList);
        zList:delete();
    end;

    -- 显示加载中界面
    ShowLoading = function(bShow)
        if (nil ~= TGMListView.pLvGames) and (nil ~= TGMListView.pLoading) then
            if TGMListView.pNoGameUI then
                TGMListView.pNoGameUI:Show(FALSE);
            end;

            if (bShow) then
                TGMListView.pLvGames:Show(FALSE);
                TGMListView.pLoading:Show(TRUE);
            else
                TGMListView.pLoading:Show(FALSE);
                TGMListView.pLvGames:Show(TRUE);
            end;
        else
            TGPLog.LogE("GMList", "Game list or loading panne is null.");
        end;
    end;

    -- 显示添加游戏
    ShowAddGame = function()
        if nil == TGMListView.pLvGames then
            TGPLog.LogE("GMList", "Shoa add game, drag list is null.");
            return;
        end;

        if not TGMListView.IsValidID(TGMListView.dwAddGame) then
            local   sItemXML;

            if TGMListView.bIsEnVer then
                sItemXML = U8toCUIStr("GameDragTipsMax_English.tpf/TenioUILayout/UIObject");
            else
                sItemXML = U8toCUIStr("GameDragTipsMax.tpf/TenioUILayout/UIObject");
            end;

            TGMListView.dwAddGame = TGMListView.pLvGames:InsertItem(0, sItemXML);
        end;

        -- 显示添加图标和文本
        ui_utility.setproperty_by_path(TGMListView.dwAddGame, "StateIcon", 
            "Background", "ONEIMAGE:bottom_bar\\bottom_bar.png?146,173,166,193;Center;0;"); 
        ui_utility.setproperty_by_path(TGMListView.dwAddGame, "ResultTxt",
            "TextColor", "RGB:255,200,0");
        ui_utility.setproperty_by_path(TGMListView.dwAddGame, "ResultTxt",
             "Caption", LoadStr(ID_ADDING_GAME_DROG_TO));
    end;

    -- 隐藏添加游戏
    HideAddGame = function()
        if nil ~= TGMListView.pLvGames and TGMListView.IsValidID(TGMListView.dwAddGame) then
            TGMListView.pLvGames:RemoveItem(0);
            TGMListView.dwAddGame = 0;
        end;
    end;

    -- ID是否有效
    IsValidID = function(dwViewID)
        return (nil ~= dwViewID) and (0 ~= dwViewID);
    end;

    -- 是否已经安装
    IsInstalled = function(nGameID)
        local   zInfo = TOfflineModule.GetGameState(nGameID);

        if nil == zInfo then
            TGPLog.LogE("GMList", "Check game state fail:"..tostring(nGameID))
            return false;
        end;

        local   nState = zInfo.iState;

        if  ierd_tgp.game_library.GAME_STATE_DOWNLOADING     == nState or
            ierd_tgp.game_library.GAME_STATE_DOWNLOAD_PAUSED == nState or
            ierd_tgp.game_library.GAME_STATE_INSTALLING      == nState or
            ierd_tgp.game_library.GAME_STATE_NOT_INSTALLED   == nState or
            ierd_tgp.game_library.GAME_STATE_DOWNLOADED      == nState or
            ierd_tgp.game_library.GAME_STATE_DOWNLOAD_FAIL   == nState then
            return false;
        else
            return true;
        end;
    end;

    OnPanelShow = function(bShow)
        if bShow and (TOfflineModule.IsRailGame(TGMListView.dwSelGame)) then
            local   zParam = {};

            zParam["GameID"] = TGMListView.dwSelGame;
            comm_center.call_service("Svr_ShowStartGame", zParam);
        else
            TOfflineBtmBar.HideView();
        end;
    end;

    -- 右键按下
    OnRBtnDown = function(pUILib, dwCtrlID, x, y)
        local   nItem = ui_utility.get_ctrl_parent_id(dwCtrlID);
        local   zItem = TGMListView.zItemMap[nItem];

        if (nil == zItem) then
            TGPLog.LogE("GMList", "Click menu, item not find:"..tostring(nItem));
            return;
        end;

        -- 显示菜单
        local   zParam = {};

        zParam["GameID" ] = zItem["GameID"];
        zParam["XOffset"] = x;
        zParam["YOffset"] = y;
        comm_center.call_service("Svr_ShowGameMenu", zParam);
    end;

    OnTickRefreshGameList = function()
        TGMListView.UpdateGameList(false);
    end;

    -- ComposeList
    pLvGames  = nil;        -- 游戏列表控件
    pLoading  = nil;        -- 加载中
    pNoGameUI = nil;        -- 没有游戏
    nBtnHome  = 0;          -- HomePage

    -- 添加游戏的节点ID
    dwAddGame = 0;          -- 添加游戏ID

    -- 标题栏
    bTtlHov   = false;      -- 悬停在标题栏
    bItemExp  = true;       -- 是否展开(默认展开)
    dwTtlIcon = 0;          -- 标题栏的ICON
    dwTitleID = 0;          -- 标题栏的ID
    pTopList  = 0;          -- 顶部的列表

    dwSelItem = 0;          -- 当前选中的ITEM
    dwSelGame = 0;

    -- 标题栏状态
    zTtlState = {};         -- 标题栏状态信息
    zItemInfo = {};         -- 顶部ITEM的状态

    zItemMap  = {};         -- ITEM <=> GameID 映射关系

    bIsEnVer  = false;      -- 是否英文版本
    ITEM_COUNT_PER_REFRESH = 10;

};